unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  FindFile, StdCtrls, Buttons, StringRoutines,IniFiles, FmxUtils,
  ComCtrls;

Const
     DefaultsFileName= 'FileBeautifier.ini';
     DuplicateStr=     '!Duplicate ';

type
  TFMain = class(TForm)
    FindFile1: TFindFile;
    Path_CDFTP: TEdit;
    BtRenameFiles: TButton;
    DebugLog: TMemo;
    Label2: TLabel;
    BtBrowse: TButton;
    MemoLog: TListBox;
    AdvancedMode: TGroupBox;
    Label1: TLabel;
    BtDummyRename: TButton;
    LogFileName: TEdit;
    Button1: TButton;
    Button2: TButton;
    BtCreateList: TBitBtn;
    ModeA: TCheckBox;
    Remove: TCheckBox;
    Phrases: TMemo;
    BoxSearchExt: TComboBox;
    Label3: TLabel;
    Dashes: TCheckBox;
    Dots: TCheckBox;
    Tracks: TCheckBox;
    procedure BtCreateListClick(Sender: TObject);
    procedure BtRenameFilesClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure BtDummyRenameClick(Sender: TObject);
    procedure RenameFiles(DoRename:Boolean);
    procedure CreateFileList;
    Function  ReplaceStrings(NewFileName:String): String;
    Function  AddFileItem(FullFileName:String):Integer;
    Function  LoadDefaults:integer;
    Function  SaveDefaults:integer;

    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure BtBrowseClick(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure ModeAClick(Sender: TObject);
    procedure RemoveClick(Sender: TObject);
    procedure LoadPhrases;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  //PFileInfo = ^TFileInfo;
  TFileInfo = class(tobject)
         FilePath    :String;
         FileName    :String;
  End;

var
  FMain: TFMain;
  FilePathList: TStringList;
  MaxFileLength:Integer;
  ApplicationPath,PhraseFileName:String;

implementation

uses FormSelectDir;

{$R *.DFM}

function DebugOutLine(s:string):integer;
begin
   //Fmain.DebugLog.Lines.Add(s);
end;

Function BeautifyFileName(s:string):string;
begin
//The order is important!
DebugOutLine(s);
if Fmain.Tracks.Checked then s:=RemoveNumericPrefix(s);
if Fmain.Dots.Checked   then s:=Convert_all_but_last_occurance('.',' ',s);
if Fmain.Dashes.Checked then s:=Convert_all_but_First_occurance('-',' ',s);
DebugOutLine(s);
       s:=char2char('_',' ',s);
       s:=char2char('[','{',s);
       s:=char2char(']','}',s);
       s:=char2char('(','{',s);
       s:=char2char(')','}',s);
       s:=del_doubleStr('{',s);
       s:=del_doubleStr('}',s);
DebugOutLine(s);
       s:=del_double_spaces(s);
DebugOutLine(s);
       s:=DelStr('()',s);
       s:=DelStr('{}',s);
DebugOutLine(s);
       s:=add_dash_rem_brakets(s);
       s:=del_spaces_from_wrong_places(s);
DebugOutLine(s);
       s:=add_spaces_in_right_places(s);
DebugOutLine(s);
       s:=lowcase(s);
       s:=Upcase_first_letters(s);
DebugOutLine(s);
       //Get Rid of potential orphant dash
       s:=StringReplace(s,' - .', '.',[]);
       s:=RemoveLeadingDash(s);
       //Just in case we run into these after previous conversions
       s:=del_doubleStr('{',s);
       s:=del_doubleStr('}',s);
       s:=Trim(del_double_spaces(s));
DebugOutLine('---');
       BeautifyFileName:=s;
end;

procedure TFMain.CreateFileList;
Var I, Max,Flength:integer;
begin
     DebugLog.Lines.Clear;
     MemoLog.items.Clear; //this might produce a small memory leak
     MaxFileLength:=0;
     FindFile1.recurse:=true;
     FindFile1.filter:=BoxSearchExt.Text;
     FindFile1.directory:=Path_CDFTP.Text;
     FindFile1.Execute;
     Max:=FindFile1.files.Count-1;
     MemoLog.Visible:=False;
     DebugLog.Lines.Add(inttostr(Max+1)+' Files Found.');
     DebugLog.Lines.Add('File Beatification in progress please wait...');
     For I:=0 to max do
         begin
         // Determine the spacing for the BatchFile
                  Flength:=length(FindFile1.files.Strings[i]);
                  if Flength>MaxFileLength then MaxFileLength:=Flength;
         AddFileItem(FindFile1.files.Strings[i])
         end;
     MemoLog.Visible:=True;
     DebugLog.Lines.Add('Beatifucation Complete.');
end;

Function TFMain.AddFileItem(FullFileName:String):Integer;
var  NewItem:TFileInfo;
     NewFileName:String;
     SameName:integer;
begin
   NewItem:=TFileInfo.create;
   NewItem.FileName:=ExtractFileName(FullFileName);
   NewItem.FilePath:=ExtractFilePath(FullFileName);
   NewFileName:=NewItem.FileName;
   NewFileName:=ReplaceStrings(NewFileName);
   NewFileName:=BeautifyFileName(NewFileName);
   NewFileName:=ReplaceStrings(NewFileName);
   With MemoLog.items do
   begin
        SameName:=IndexOf(NewFileName);
        if SameName>-1 then
                     NewFileName:=DuplicateStr+NewFileName;
        AddFileItem:=Addobject(NewFileName,NewItem);
   end;
end;

procedure TFMain.BtCreateListClick(Sender: TObject);
begin
     CreateFileList;
end;


Function TFMain.ReplaceStrings(NewFileName:string): string;
//Replaces SubStrings in NewFileName using | as delimiter for new SubString
Var I, Max:integer;
	OldStr,NewStr:String;
	RenameStrings:TStrings;
begin
	Max:=phrases.lines.Count-1;
	For I:=0 to Max do
    begin
		RenameStrings:=Split(phrases.lines[i],'|');
      	//DebugLog.Lines.Add( toStr(RenameStrings.Count) );
		if RenameStrings.Count>0 then
		begin
			OldStr:=Trim(RenameStrings[0]);
			if RenameStrings.Count<2 then
				NewStr:=''
			else
         NewStr:=Trim(RenameStrings[1]);
         //Handle _ as spaces in replace strings
         OldStr:=StringReplace(OldStr,'_',' ',[rfReplaceAll]);
         NewStr:=StringReplace(NewStr,'_',' ',[rfReplaceAll]);
			NewFileName:=StringReplace(NewFileName,OldStr,NewStr,[rfReplaceAll,rfIgnoreCase]);
			//DebugLog.Lines.Add('&'+OldStr+'--'+NewStr+'&');
		end ;
    end;
    ReplaceStrings:=NewFileName;
end;

procedure TFMain.RenameFiles(DoRename:Boolean);
Var I, Max,MaxFound:integer;
    FilePath,OldName,NewName:String;
    F : TextFile;
begin
     If DoRename then
       DebugLog.Lines.Add('Starting File Rename.')
     else
       DebugLog.Lines.Add('Starting Batch Generation.');

     Max:=MemoLog.items.Count-1;
     MaxFound:=FindFile1.files.Count-1;
     if Max <MaxFound then
     begin
        ShowMessage(inttostr(MaxFound-Max)+' Filenames missing from the list!');
        DebugLog.Lines.Add('Either you have delted files from the File List');
        DebugLog.Lines.Add('Or there were too many mp3s found.');
        DebugLog.Lines.Add('In the second move some files into multiple subdirs and process them seperetly.');
        DebugLog.Lines.Add('');
        DebugLog.Lines.Add('...Sorry For the Inconvenience but I don''t have a Good unlimited text component.');
        DebugLog.Lines.Add('All of them Cost $$$. Bill was stupid enough to impose 32K limits on the standard win9x memos.');
        exit;
     end else
     begin
     AssignFile(F, ApplicationPath+LogFileName.Text);
     Rewrite(F);
     For I:=0 to max do
         begin
              NewName:=MemoLog.items[i];
              OldName:=TFileInfo(MemoLog.items.objects[i]).FileName;
              FilePath:=TFileInfo(MemoLog.items.objects[i]).FilePath;
              Writeln(F,'REN '+Padright(MaxFileLength+4,'"'+FilePath+OldName+'"')+'"'+NewName+'"');
              If DoRename then RenameFile(FilePath+OldName,FilePath+NewName);
         end;
     CloseFile(F);
     end;
     DebugLog.Lines.Add('Done.');
end;

procedure TFMain.BtRenameFilesClick(Sender: TObject);
begin
     CreateFileList;
     RenameFiles(True);
end;

procedure TFMain.FormCreate(Sender: TObject);
begin
    FilePathList:= TStringList.Create;
    ApplicationPath:=Extractfilepath(application.exename);
    DebugLog.Lines.Clear;
    DebugLog.Lines.Add('Please do not delete filenames from the File List Memo!!!');
    LoadDefaults;
end;

procedure TFMain.BtDummyRenameClick(Sender: TObject);
begin
     RenameFiles(False);
end;


Function TFmain.LoadDefaults:integer;
var
   IniFile :  TIniFile;
   FileName:  String;
begin
   FileName:=ApplicationPath+DefaultsFileName;
   IniFile := TIniFile.Create(FileName);
   try
    with IniFile do
    begin
    Path_CDFTP.Text      	:=ReadString('Defaults','Path_CDFTP'  ,'C:\Mp3s');
    LogFileName.Text        :=ReadString('Defaults','LogFileName'  ,'FileRename.Bat');
    PhraseFileName          :=ReadString('Defaults','PhraseFileName'  ,'Phrases.txt');
    Phrases.Lines.LoadFromFile(PhraseFileName);
    LoadDefaults:=0;
    end;
   finally
    IniFile.Free;
  end;
end;

Function TFmain.SaveDefaults:integer;
var
   IniFile :  TIniFile;
   FileName:  String;
begin
   FileName:=ApplicationPath+DefaultsFileName;
   IniFile := TIniFile.Create(FileName);
   try
    with IniFile do
    begin
    WriteString('Defaults','Path_CDFTP'  ,Path_CDFTP.Text);
    WriteString('Defaults','LogFileName'  ,LogFileName.Text);
    SaveDefaults:=0;
    end;
   finally
    IniFile.Free;
  end;
end;

procedure TFMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    SaveDefaults;
end;

procedure TFMain.BtBrowseClick(Sender: TObject);
begin
    FSelectDir.CurrentDir.Text:=Path_CDFTP.Text;
    FSelectDir.Show;
end;

procedure TFMain.Button2Click(Sender: TObject);
begin
     DebugLog.Lines.Add('Executing: '+ApplicationPath+LogFileName.Text +' in '+ApplicationPath);
     ExecuteFile('CMD',ApplicationPath+LogFileName.Text, ApplicationPath, SW_SHOW)
end;

procedure TFMain.Button1Click(Sender: TObject);
begin
    ExecuteFile('Notepad.exe', ApplicationPath+LogFileName.Text, '', SW_SHOW)
end;

procedure TFMain.ModeAClick(Sender: TObject);
begin
    AdvancedMode.Visible:=ModeA.Checked;
end;

procedure TFMain.RemoveClick(Sender: TObject);
begin
    LoadPhrases;
end;

procedure TFMain.LoadPhrases;
begin
   If remove.Checked then
       Phrases.Lines.LoadFromFile(PhraseFileName)
   else
       Phrases.Lines.Clear
end;

end.